<template>
	<eInput v-model="searchValue" placeholder="快速查找组件" icon="ios-search" style="margin-top: 12px" />

  <eTabs>
    <eTabPane
      v-for="level in elements"
      :key="level.value"
      :name="level.value"
      :label="level.label"
    >
      <fieldset
        v-for="group in level.groups"
        :key="group.value"
        class="drop-group"
      >
        <legend class="title">{{ group.label }}</legend>
        <draggable
          :list="group.elements"
          itemKey="drag.compName"
          :sort="false"
          class="group-content"
          :group="{ name: 'dragsource', pull: 'clone', put: false }"
          :clone="cloneItem"
          :animation="300"
          :move="handleCompMove"
          @start="handleDragStart"
          @end="handleDragEnd"
        >
          <template #item="{ element }">
            <div class="drag-cell">
              <SvgIcon :iconName="element.drag.icon" className="drag-icon"></SvgIcon>
              <p class="drag-name">{{ element.drag.label }}</p>
            </div>
          </template>
        </draggable>
      </fieldset>
    </eTabPane>
  </eTabs>
</template>

<script setup lang="ts">
import draggable from 'vuedraggable'
import { v4 as uuidv4 } from 'uuid'
import { computed, ref } from 'vue'
import components from '../config'
import type { ChannelEnum } from '../types'
import useViewEditorStore from '@/store/viewEditor'

interface IProps {
	channel: `${ChannelEnum}`,
  dragging: boolean
}

const props = defineProps<IProps>()

const emit = defineEmits(['update:dragging'])

const searchValue = ref('')
const { updateDragResources } = useViewEditorStore()
function cloneItem(original: any) {
  const ele = JSON.parse(JSON.stringify({
    id: uuidv4(),
    selected: true,
    ...original
  }))
  // 给元素的每个配置项添加id，使之被认为是不同的组件从而避免值覆盖问题
  Object.keys(ele.configs).forEach(key => {
    if (ele.configs[key]) {
      ele.configs[key]['id'] = uuidv4()
    }
  })
  if (ele.drag.classify && ele.drag.classify.value === 'layout') {
    const columns = ele.data.props.columns || []
    ele.data.props.columns = columns.map((col: any) => {
      return {
        ...col,
        id: uuidv4(),
        list: []
      }
    })
  }
  return ele
}

function handleCompMove(event: any) {
  // 防止布局元素嵌套拖拽
  const { classify } = event.draggedContext.element.drag
  if (classify.value === 'layout') {
    const classList = event.to.classList
    return !(classList.contains('widget-col-list')
      || classList.contains('ele-container'))
  }
  return true
}

const handleDragStart = (event: any) => {
  emit('update:dragging', true)
}

const handleDragEnd = (event: any) => {
  emit('update:dragging', false)
}

const elements = computed(() => {
  const filterComponents = components
		.filter(
			(i) =>
				(!searchValue.value || i.drag.compName.includes(searchValue.value) || i.drag.label.includes(searchValue.value)) &&
				i.drag.channel === props.channel
		)
  updateDragResources(filterComponents)
  return filterComponents
    .reduce((prev, cur) => {
      if (cur.drag.classify.value !== 'page') {
        const classify = prev.find((item: any) => item.value === cur.drag.classify.value)
        if (classify) {
          const group = classify.groups.find((item: any) => item.value === cur.drag.group.value)
          if (!group) {
            classify.groups.push({
              ...cur.drag.group,
              elements: [cur]
            })
          } else {
            group.elements.push(cur)
          }
        } else {
          prev.push({
            ...cur.drag.classify,
            groups: [
              {
                ...cur.drag.group,
                elements: [cur]
              }
            ]
          })
        }
      }
      return prev
		}, [])
})
</script>

<style lang="less" scoped>
  @color: #4d72dd;
  .drop-group {
    border: 1px solid @color;
    margin: 0;
    padding: 6px 12px;
    .title {
      padding: 2px 4px;
      margin-left: 4px;
      color: @color;
    }
  }
  .group-content {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: -4px;
    .drag-cell {
      text-align: center;
      padding: 4px;
      .drag-icon {
        margin: 8px 0;
        color: #596b8c;
      }
      .drag-name {
        font-size: 12px;
      }
      &:hover {
        cursor: grab;
        color: #ffffff;
        background: rgba(31, 35, 41, 0.5);
        border-radius: 6px;
        .drag-icon {
          color: #ffffff;
        }
      }
    }
  }
  .sortable-drag {
    cursor: grabbing !important;
  }
</style>
